package com.example.chinesenation.Controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;




import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.chinesenation.Entity.*;
import com.example.chinesenation.Exception.AuthenException;
import com.example.chinesenation.Redis.RedisService;
import com.example.chinesenation.Response.ResultType;
import com.example.chinesenation.Response.ServerResponse;
import com.example.chinesenation.Service.*;
import com.example.chinesenation.Utils.*;
import com.example.chinesenation.VO.Introduction;
import com.example.chinesenation.VO.MainPage.VOArticleList;
import com.example.chinesenation.VO.MainPage.VOPolicyList;
import com.example.chinesenation.VO.NationPage.*;
import com.example.chinesenation.VO.VOArticle;




import com.example.chinesenation.VO.VOPolicy;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;


import java.util.*;
import java.util.stream.Collectors;

/**
 * @author sakuraFallingDown
 * @version 1.0
 * @date 2021/1/18 16:22
 */
@Controller
@ResponseBody
@RequestMapping("/nation")
@CrossOrigin
public class NationController {//民族模块的接口

    private final Logger logger= LoggerFactory.getLogger(getClass());


    @Autowired
    private Audience audience;

    @Autowired
    private IBrowseRecordService browseRecordService;

    @Autowired
    private IArticleService articleService;

    @Autowired
    private ICollectService collectService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private INationService nationService;

    @Autowired
    private IResourcesService resourcesService;

    @Autowired
    private INationAgePartitionService nationAgePartitionService;
    @Autowired
    private INationBirthStatusPartitionService nationBirthStatusPartitionService;
    @Autowired
    private INationDisableworkPartitionService nationDisableworkPartitionService;
    @Autowired
    private INationEducationPartitionService nationEducationPartitionService;
    @Autowired
    private INationIndustryPartitionService nationIndustryPartitionService;
    @Autowired
    private INationMaritalStatusPartitionService nationMaritalStatusPartitionService;

    @Autowired
    private IAttentionService attentionService;

    @Autowired
    private NationTools nationUtil;

    @Autowired
    private RecommendedTools recommendedTools;



    /**
     *
     * @param token 用户的token
     * @param id 文章的主键id
     * @param ip 用户浏览的ip ip用于做基数统计
     * @return 返回该id对应的文章信息
     */
    @ApiOperation("查看主键为参数id的文章具体信息接口")
    @RequestMapping("/article/{id}")//查看文章信息
    private ServerResponse<VOArticle> getVoArticle(@RequestHeader(value = "token", required = false) String token,
                                                   @PathVariable("id") String id,
                                                   @RequestHeader(value = "ip",required = false)String ip){

        if(token!=null&&!token.equals("")){
            String uid= JwtTokenUtil.getUserId(token,audience);
            if(!browseRecordService.savaRecord(uid,id)){
                logger.error("插入浏览记录失败uid:"+uid+",浏览文章id:"+id);
            }else{
                recommendedTools.ChangeUserInterestArticleVectorByInterView(uid,id);//异步任务实现用户特征兴趣矩阵的修改
            }
        }
        VOArticle voArticle=new VOArticle();
        if(redisService!=null&&redisService.hasComment(CommonURL.RedisArticle+id)){

            Object object=redisService.get(CommonURL.RedisArticle +id);//防止缓存穿透
            if(object==null){
                return ServerResponse.createErrorsResponse(ResultType.NOTEXITS);
            }
            voArticle=(VOArticle)object;
            redisService.addPageView(CommonURL.RedisArticlePageView+id,ip);//增加阅读量
            int pageView=redisService.getPageView(CommonURL.RedisArticlePageView+id);
            voArticle.setPageview(voArticle.getPageview()+pageView);

            return ServerResponse.createSuccessResponse("查找文章信息成功",voArticle);
        }
        Article article=articleService.getById(id);
        if(article==null) {
            redisService.putMinute(CommonURL.RedisPolicy+ id,null,30);//设置半小时的空值缓存，防止缓存穿透
            throw new AuthenException(ResultType.NOTEXITS);
        }
        DataChanges.fromArticleToVOArticle(article, voArticle);
        if(voArticle!=null) redisService.put(CommonURL.RedisArticle +id,voArticle,24);//不为空，则永久存入redis
        redisService.addPageView(CommonURL.RedisArticlePageView+id,ip);//增加阅读量
        voArticle.setPageview(voArticle.getPageview()+1);
        return ServerResponse.createSuccessResponse("查找文章信息成功",voArticle);
    }


    /**
     *
     * @param token 用户id
     * @param id 文章id
     * @return 返回收藏操作是否成功，data属性为null
     */
    @ApiOperation("收藏主键为ID的文章接口")
    @PostMapping("/article/collect")//收藏某个id的文章
    private ServerResponse<String> CollectArticle(@RequestHeader(value = "token", required = true) String token,
                                                  @RequestParam(value = "id") String id){

        if(token!=null&&!token.equals("")){
            String uid= JwtTokenUtil.getUserId(token,audience);
            Collect collect=new Collect();
            collect.setArticleId(id);
            collect.setUid(uid);
            if(collectService.save(collect)){
                recommendedTools.ChangeUserInterestArticleVectorByCollect(uid,id,true);//异步任务修改用户兴趣矩阵
                return ServerResponse.createSuccessResponse("收藏成功",null);
            }else{
                return ServerResponse.createErrorsResponse(ResultType.ERROR);
            }
        }else{
            return ServerResponse.createErrorsResponse(ResultType.TOKENNULL);
        }
    }
    /**
     *
     * @param token 用户id
     * @param id 文章id
     * @return 返回取消收藏操作是否成功，data属性为null
     */
    @ApiOperation("取消收藏主键为ID的文章接口")
    @PostMapping("/article/dropcollect")//取消收藏某个id的文章，按照uid和文章id
    private ServerResponse<String> DropCollectArticle(@RequestHeader(value = "token", required = true) String token,
                                                      @RequestParam(value = "id")String id){
        if(token!=null&&!token.equals("")){
            String uid= JwtTokenUtil.getUserId(token,audience);
            QueryWrapper<Collect> qw=new QueryWrapper<>();
            qw.eq("uid",uid);
            qw.eq("article_id",id);
            if(collectService.remove(qw)){
                recommendedTools.ChangeUserInterestArticleVectorByCollect(uid,id,false);//异步任务修改用户兴趣矩阵，这里的false表示操作减
                return ServerResponse.createSuccessResponse("取消收藏成功",null);
            }else{
                return ServerResponse.createErrorsResponse(ResultType.ERROR);
            }
        }else{
            return ServerResponse.createErrorsResponse(ResultType.TOKENNULL);
        }
    }

    /**
     *
     * @param token 用户id
     * @param id 文章id
     * @return 返回该文章是否已经被该token的用户收藏过了，data属性为null，在msg中返回true or false
     */
    @ApiOperation("判断主键为ID的文章是否被目标用户收藏过的接口")
    @PostMapping("/article/iscollect")//判断某个id的文章是否收藏过
    private ServerResponse<String> isCollectArticle(@RequestHeader(value = "token", required = true) String token,
                                                    @RequestParam(value = "id")String id){
        if(token!=null&&!token.equals("")){
            String uid= JwtTokenUtil.getUserId(token,audience);
            QueryWrapper<Collect> qw=new QueryWrapper<>();
            qw.eq("uid",uid);
            qw.eq("article_id",id);
            if(collectService.getOne(qw)!=null){
                return ServerResponse.createSuccessResponse("true",null);
            }else{
                return ServerResponse.createSuccessResponse("false",null);
            }
        }else{
            return ServerResponse.createErrorsResponse(ResultType.TOKENNULL);
        }
    }


    /**
     *
     * @return 返回民族模块的主界面所需要的数据，具体的数据类型为VONationMainPage
     * private List<Resources> resources;//首页资源图片
     * private List<VOArticleList> articleLists;//今日热门和推荐
     * private HashMap<String,List<VONationArticle>> data;//自带的几个模块的内容
     *
     */
    //民族模块主界面数据获取
    @ApiOperation("民族模块的主界面获取数据接口")
    @RequestMapping("/nation")
    private ServerResponse<VONationMainPage> nationMainPage(@RequestHeader(value = "token",required = false)String token){//民族主页
        VONationMainPage voNationPage=new VONationMainPage();

        List<VOArticleList> articleLists=new ArrayList<>();
        if(token!=null&&!token.equals("")){//存在登录用户，开启个性化推荐
            String uid=JwtTokenUtil.getUserId(token,audience);
            voNationPage.setArticleLists(recommendedTools.recommendedArticle(uid));//用户个性化推荐内容
        }else {//去redis缓存查找总榜
            if (redisService != null && redisService.hasKey(CommonURL.MainPageArticle)) {
                articleLists = (List<VOArticleList>) redisService.get(CommonURL.MainPageArticle);
                articleLists = MainController.getRankArticle(articleLists, articleService, redisService);
                voNationPage.setArticleLists(articleLists);
            }
        }
        
        //民族资源轮播，主页轮播图
        List<Resources> resources = null;
        if(redisService!=null&&redisService.hasKey(CommonURL.NationMainPageResources)){
            resources=(List<Resources>)redisService.get(CommonURL.NationMainPageResources);
        }
        if(resources==null){
            IPage<Resources> iPage=new Page<>(1,5);
            resources= resourcesService.page(iPage).getRecords();
            if(resources!=null&&resources.size()!=0){
                resources.forEach(resource->{
                    resource.setResUrl(CommonURL.imgUrl+resource.getResUrl());
                });
                redisService.put("nation:resources",resources);
            }
        }
        if(resources!=null){
            voNationPage.setResources(resources);
        }
        //民族主界面每个模块的包含所有民族的数据
        if(redisService!=null&&redisService.hasKey(CommonURL.NationMainPageArticle)){
            HashMap<String,List<VONationArticle>> data=new HashMap<>();
            data=(HashMap<String,List<VONationArticle>>)redisService.get(CommonURL.NationMainPageArticle);
            if (data.size() != 0) {
                voNationPage.setData(data);
            }
        }else {
            List<String> categoryName = nationUtil.getCategoryName();
            HashMap<String, List<VONationArticle>> data = new HashMap<>();
            categoryName.forEach(category -> {
                List<VONationArticle> voNationArticleList = new ArrayList<>();
                QueryWrapper<Article> qw = new QueryWrapper<>();
                qw.eq("category_name", category);
                qw.orderByDesc("pageview");
                IPage<Article> iPage = new Page<>(1, 10);
                IPage<Article> articleIPage = articleService.page(iPage, qw);
                List<Article> records = articleIPage.getRecords();
                if(records!=null&&records.size()!=0) {
                    voNationArticleList = records.stream().map(record -> {
                        VONationArticle voNationArticle = new VONationArticle();
                        DataChanges.fromArticleToVONationArticle(record, voNationArticle);
                        return voNationArticle;
                    }).collect(Collectors.toList());
                    data.put(category, voNationArticleList);
                }
            });
            if (data.size() != 0) {
                voNationPage.setData(data);
                redisService.put(CommonURL.NationMainPageArticle,data,1);//设置一小时有效，一小时会自动统计阅读量，所以会更新缓存
            }
        }
        return ServerResponse.createSuccessResponse("请求成功",voNationPage);
    }


    /**
     *
     * @param nationName 民族名字
     * @return 返回该民族所有的信息，具体可以查看VONationPage
     *
     */
    @ApiOperation("民族模块的每个民族主页面获取数据接口")
    @RequestMapping("/nation/nation")
    private ServerResponse<VONationPage> nationMainPageByNationName(
            @RequestParam(value = "nationName") String nationName){
        VONationPage voNationPage=new VONationPage();
        //装配民族名
        voNationPage.setNationName(nationName);

        //装配民族介绍
        Nation nation=(Nation)redisService.get(CommonURL.NationIntroduction+nationName);
        if(nation==null) {//缓存不存在则去数据库查找
            QueryWrapper<Nation> qw = new QueryWrapper<>();
            qw.eq("nation_name", nationName);
            nation= nationService.getOne(qw);
            if(nation!=null){
                redisService.put(CommonURL.NationIntroduction+nationName,nation);
            }
        }
        if(nation!=null){
            Introduction introduction= JSON.parseObject(nation.getNationIntroduction(),Introduction.class);
            voNationPage.setIntroduction(introduction.getNation_introduction());
        }else{
            return ServerResponse.createErrorsResponse(ResultType.ERROR);
        }

        //获取该民族热点文章信息
        List<VONationArticle> articleLists=new ArrayList<>();
        articleLists=(List<VONationArticle>)redisService.get(CommonURL.NationPageRecommend+nationName);
        if (articleLists==null) {//默认存在redis中，每个民族的推荐的文章列表,如果缓存失效，则自己去获取，并存入redis缓存
            articleLists=nationUtil.getNationHotArticle(nationName);
        }
        voNationPage.setArticleLists(articleLists);

        //获取该民族首页图资源
        Resources resources;
        resources=(Resources)redisService.get(CommonURL.NationPageResources+nationName);
        if(resources==null){
            QueryWrapper<Resources> qw = new QueryWrapper<>();
            qw.eq("res_description", nationName);
            resources= resourcesService.getOne(qw);
            resources.setResUrl(CommonURL.imgUrl+resources.getResUrl());
            if(resources!=null){
                redisService.put(CommonURL.NationPageResources+nationName,resources);
            }
        }
        if(resources!=null){
            voNationPage.setResources(resources);
        }

        //获取该民族的每个模块的数据
        if(redisService!=null&&redisService.hasKey(CommonURL.NationPageArticle+nationName)){
            HashMap<String,List<VONationArticle>> data=new HashMap<>();
            data=(HashMap<String,List<VONationArticle>>)redisService.get(CommonURL.NationPageArticle+nationName);
            if (data.size() != 0) {
                voNationPage.setData(data);
            }
        }else {
            List<String> categoryName = nationUtil.getCategoryName();
            HashMap<String, List<VONationArticle>> data = new HashMap<>();
            categoryName.forEach(category -> {
                List<VONationArticle> voNationArticleList = new ArrayList<>();
                QueryWrapper<Article> qw = new QueryWrapper<>();
                qw.eq("nation_name", nationName);
                qw.eq("category_name", category);
                qw.orderByDesc("pageview");
                IPage<Article> iPage = new Page<>(1, 10);
                IPage<Article> articleIPage = articleService.page(iPage, qw);
                List<Article> records = articleIPage.getRecords();
                if(records.size()!=0) {
                    records.forEach(article -> {
                        VONationArticle voNationArticle = new VONationArticle();
                        DataChanges.fromArticleToVONationArticle(article, voNationArticle);
                        voNationArticleList.add(voNationArticle);
                    });
                    data.put(category, voNationArticleList);
                }
            });
            if (data.size() != 0) {
                voNationPage.setData(data);
                redisService.put(CommonURL.NationPageArticle+nationName,data,1);//设置一小时有效，一小时会自动统计阅读量，所以会更新缓存
            }
        }

        /**
         * 计算获取该民族人口分布情况
         * 总共分为以下几种数据
         *
         * 1.年龄分布
         * 2.生育情况统计
         * 3.未工作及原因人口统计
         * 4.受教育程度统计
         * 5.各行业工作情况统计
         * 6.婚姻状况统计
         */
        HashMap<String,NationPopulation> nationAgePartition=new HashMap<>();//该民族年龄分布
        HashMap<String,NationPopulation> nationBirthStatus=new HashMap<>();//该民族生育情况统计
        HashMap<String,NationPopulation> nationDisableWork=new HashMap<>();//该民族为工作人口统计
        HashMap<String,NationPopulation> nationEducation=new HashMap<>();//该民族受教育程度统计
        HashMap<String,NationPopulation> nationIndustry=new HashMap<>();//该民族工作情况统计
        HashMap<String,NationPopulation> nationMaritalStatus=new HashMap<>();//该民族婚宴状况统计

        if(redisService!=null&&redisService.hasKey(CommonURL.NationAgePartition+nationName)){
            nationAgePartition=(HashMap<String,NationPopulation>)redisService.get(CommonURL.NationAgePartition+nationName);
        }
        if(redisService!=null&&redisService.hasKey(CommonURL.NationAgePartition+nationName)){
            nationBirthStatus=(HashMap<String,NationPopulation>)redisService.get(CommonURL.NationBirthStatus+nationName);
        }
        if(redisService!=null&&redisService.hasKey(CommonURL.NationAgePartition+nationName)){
            nationDisableWork=(HashMap<String,NationPopulation>)redisService.get(CommonURL.NationDisableWork+nationName);
        }
        if(redisService!=null&&redisService.hasKey(CommonURL.NationAgePartition+nationName)){
            nationEducation=(HashMap<String,NationPopulation>)redisService.get(CommonURL.NationEducation+nationName);
        }
        if(redisService!=null&&redisService.hasKey(CommonURL.NationAgePartition+nationName)){
            nationIndustry=(HashMap<String,NationPopulation>)redisService.get(CommonURL.NationIndustry+nationName);
        }
        if(redisService!=null&&redisService.hasKey(CommonURL.NationMaritalStatus+nationName)){
            nationMaritalStatus=(HashMap<String,NationPopulation>)redisService.get(CommonURL.NationMaritalStatus+nationName);
        }
        if(nationAgePartition==null||nationAgePartition.size()==0){
            nationAgePartition=new HashMap<>();
            QueryWrapper<NationAgePartition> qw=new QueryWrapper<>();
            qw.eq("nation_name",nationName);
            qw.like("age","岁");
            List<NationAgePartition> nationAgePartitions = nationAgePartitionService.list(qw);
            HashMap<String, NationPopulation> finalNationAgePartition = nationAgePartition;
            nationAgePartitions.forEach(object->{
                NationPopulation np=new NationPopulation();
                np.setFemale(object.getFemaleNumber());
                np.setMale(object.getMaleNumber());
                np.setCount(""+(Integer.parseInt(object.getMaleNumber())
                        +Integer.parseInt(object.getFemaleNumber())));
                finalNationAgePartition.put(object.getAge(), np);
            });
            nationAgePartition=finalNationAgePartition;
            if(nationAgePartition!=null&&nationAgePartition.size()!=0){
                redisService.put(CommonURL.NationAgePartition+nationName,nationAgePartition);
            }
        }
        if(nationBirthStatus==null||nationBirthStatus.size()==0){
            nationBirthStatus=new HashMap<>();
            QueryWrapper<NationBirthStatusPartition> qw=new QueryWrapper<>();
            qw.eq("nation_name",nationName);
            List<NationBirthStatusPartition> nationBirthStatusPartitions = nationBirthStatusPartitionService.list(qw);
            HashMap<String, NationPopulation> finalNationAgePartition = nationBirthStatus;
            nationBirthStatusPartitions.forEach(object->{
                NationPopulation np=new NationPopulation();
                np.setFemale(object.getFemaleNumber());
                np.setMale(object.getMaleNumber());
                np.setCount(object.getTotalNumber());
                finalNationAgePartition.put(object.getCurrentBirthStatus(), np);
            });
            nationBirthStatus=finalNationAgePartition;
            if(nationBirthStatus!=null&&nationBirthStatus.size()!=0){
                redisService.put(CommonURL.NationBirthStatus+nationName,nationBirthStatus);
            }
        }
        if(nationDisableWork==null||nationDisableWork.size()==0){
            nationDisableWork=new HashMap<>();
            QueryWrapper<NationDisableworkPartition> qw=new QueryWrapper<>();
            qw.eq("nation_name",nationName);
            List<NationDisableworkPartition> nationDisableworkPartitions = nationDisableworkPartitionService.list(qw);
            HashMap<String, NationPopulation> finalNationAgePartition = nationDisableWork;
            nationDisableworkPartitions.forEach(object->{
                NationPopulation np=new NationPopulation();
                np.setFemale(object.getFemaleNumber());
                np.setMale(object.getMaleNumber());
                np.setCount(object.getTotalNumber());
                finalNationAgePartition.put(object.getCurrentDisablework(), np);
            });
            nationDisableWork=finalNationAgePartition;
            if(nationDisableWork!=null&&nationDisableWork.size()!=0){
                redisService.put(CommonURL.NationDisableWork+nationName,nationDisableWork);
            }
        }
        if(nationEducation==null||nationEducation.size()==0){
            nationEducation=new HashMap<>();
            QueryWrapper<NationEducationPartition> qw=new QueryWrapper<>();
            qw.eq("nation_name",nationName);
            List<NationEducationPartition> nationEducationPartitions = nationEducationPartitionService.list(qw);
            HashMap<String, NationPopulation> finalNationAgePartition = nationEducation;
            nationEducationPartitions.forEach(object->{
                NationPopulation np=new NationPopulation();
                np.setFemale(object.getFemaleNumber());
                np.setMale(object.getMaleNumber());
                np.setCount(object.getTotalNumber());
                finalNationAgePartition.put(object.getCurrentEducation(), np);
            });
            nationEducation=finalNationAgePartition;
            if(nationEducation!=null&&nationEducation.size()!=0){
                redisService.put(CommonURL.NationEducation+nationName,nationEducation);
            }
        }
        if(nationIndustry==null||nationIndustry.size()==0){
            nationIndustry=new HashMap<>();
            QueryWrapper<NationIndustryPartition> qw=new QueryWrapper<>();
            qw.eq("nation_name",nationName);
            List<NationIndustryPartition> nationIndustryPartitions = nationIndustryPartitionService.list(qw);
            HashMap<String, NationPopulation> finalNationAgePartition = nationIndustry;
            nationIndustryPartitions.forEach(object->{
                NationPopulation np=new NationPopulation();
                np.setFemale(object.getFemaleNumber());
                np.setMale(object.getMaleNumber());
                np.setCount(object.getTotalNumber());
                finalNationAgePartition.put(object.getCurrentIndustry(), np);
            });
            nationIndustry=finalNationAgePartition;
            if(nationIndustry!=null&&nationIndustry.size()!=0){
                redisService.put(CommonURL.NationIndustry+nationName,nationIndustry);
            }
        }
        if(nationMaritalStatus==null||nationMaritalStatus.size()==0){
            nationMaritalStatus=new HashMap<>();
            QueryWrapper<NationMaritalStatusPartition> qw=new QueryWrapper<>();
            qw.eq("nation_name",nationName);
            List<NationMaritalStatusPartition> nationMaritalStatusPartitions = nationMaritalStatusPartitionService.list(qw);
            HashMap<String, NationPopulation> finalNationAgePartition = nationMaritalStatus;
            nationMaritalStatusPartitions.forEach(object->{
                NationPopulation np=new NationPopulation();
                np.setFemale(object.getFemaleNumber());
                np.setMale(object.getMaleNumber());
                np.setCount(object.getTotalNumber());
                finalNationAgePartition.put(object.getCurrentMaritalStatus(), np);
            });
            nationMaritalStatus=finalNationAgePartition;
            if(nationMaritalStatus!=null&&nationMaritalStatus.size()!=0){
                redisService.put(CommonURL.NationMaritalStatus+nationName,nationMaritalStatus);
            }
        }
        voNationPage.setNationAgePartition(nationAgePartition);
        voNationPage.setNationBirthStatus(nationBirthStatus);
        voNationPage.setNationDisableWork(nationDisableWork);
        voNationPage.setNationEducation(nationEducation);
        voNationPage.setNationIndustry(nationIndustry);
        voNationPage.setNationMaritalStatus(nationMaritalStatus);
        return ServerResponse.createSuccessResponse("请求成功",voNationPage);

    }



    /**此接口用于筛选符合nationName，categoryName的文章集合
     *
     * @param nationName 筛选的民族民资
     * @param categoryName 筛选的文章种类
     *
     * @return 返回符合筛选条件的文章信息
     *
     * 注意：
     * 如果是某个民族的主页调用接口，想要了解该民族的categoryName所有的信息
     * 应该传nationName和categoryName（必须）。
     */
    @ApiOperation("民族模块的每个民族的某个categoryName获取数据接口")
    @RequestMapping("/nation/nation/category")
    private ServerResponse<VONationCategoryPage> nationMainPageByNationAndCategory(
            @RequestParam(value = "nationName" ) String nationName
            ,@RequestParam(value = "categoryName") String categoryName){
        VONationCategoryPage voNationPage=new VONationCategoryPage();
        //每个模块的具体的数据
        if(redisService!=null&&redisService.hasKey(CommonURL.NationPageArticle+nationName+":"+categoryName)){
            HashMap<String,List<VONationArticle>> data=new HashMap<>();
            data=(HashMap<String,List<VONationArticle>>)redisService.get(CommonURL.NationPageArticle+nationName+":"+categoryName);
            if (data.size() != 0) {
                voNationPage.setData(data);
            }
        }else {
            HashMap<String,List<VONationArticle>> data=new HashMap<>();
            List<String> moduleName = nationUtil.getModuleName().get(categoryName);
            moduleName.forEach(module->{
                List<VONationArticle> voNationArticleList=new ArrayList<>();
                QueryWrapper<Article> qw=new QueryWrapper<>();
                qw.eq("nation_name",nationName);
                qw.eq("category_name",categoryName);
                qw.eq("Module_name",module);
                qw.orderByDesc("pageview");
                IPage<Article> iPage=new Page<>(1,10);
                IPage<Article> articleIPage = articleService.page(iPage, qw);
                List<Article> records = articleIPage.getRecords();
                if(records.size()!=0) {//存储不为空的module值
                    records.forEach(article -> {
                        VONationArticle voNationArticle = new VONationArticle();
                        DataChanges.fromArticleToVONationArticle(article, voNationArticle);
                        voNationArticleList.add(voNationArticle);
                    });
                    data.put(module, voNationArticleList);
                }
            });
            if (data.size() != 0) {
                voNationPage.setData(data);
                redisService.put(CommonURL.NationPageArticle+nationName+":"+categoryName,data,1);//设置一小时有效，一小时会自动统计阅读量，所以会更新缓存
            }
        }
        return ServerResponse.createSuccessResponse("请求成功",voNationPage);

    }

    public int findIntegers(int n){//小于这个
        int dp[]=new int[33];
        dp[0]=dp[1]=1;
        for(int i=2;i<32;i++){
            dp[i]=dp[i-1]+dp[i-2];
            //分别为0和为1的满足的数字
        }
        int pre=0;
        int res=0;
        for(int i=29;i>=0;i--){
            int val=(i<<1);
            if((n&val)!=0){
                res+=dp[i+1];//加上比其小的，如果此处不为0，那么就是dpi+1
                if(pre==1){
                    break;
                }
                pre=1;
            }else{
                pre=0;
            }
            if(i==0) res++;
        }
        return res;
    }

    /**此接口用于筛选符合nationName，categoryName，以及moduleName的文章集合
     *
     * @param nationName 筛选的民族民资
     * @param categoryName 筛选的文章种类
     * @param moduleName 筛选文章的模块
     * @return 返回符合筛选条件的文章信息
     *
     * 注意：
     * 如果是某个民族的主页调用接口，想要了解该民族的categoryName的moduleName的所有的信息，
     * 应该传nationName和categoryName和moduleName（必须）
     *
     *
     */
    @ApiOperation("民族模块中获取每个民族的某个category的moduleName的所有数据接口")
    @RequestMapping("/nation/nation/category/module")
    private ServerResponse<VONationModulePage> nationMainPageByNationAndCategoryAndModule(
            @RequestParam(value = "nationName") String nationName
            ,@RequestParam(value = "categoryName") String categoryName
            ,@RequestParam(value = "moduleName") String moduleName
            ,@RequestParam(value = "current")int current
            ,@RequestParam(value = "size")int size){
        VONationModulePage voNationPage=new VONationModulePage();
        //某个类别的某个模块的所包含的文章信息
        List<VONationArticle> voNationArticleList = new ArrayList<>();
        QueryWrapper<Article> qw = new QueryWrapper<>();
        qw.eq("nation_name",nationName);
        qw.eq("category_name", categoryName);
        qw.eq("Module_name", moduleName);
        qw.orderByDesc("pageview");
        IPage<Article> iPage = new Page<>(current, size);
        IPage<Article> articleIPage = articleService.page(iPage, qw);
        List<Article> records = articleIPage.getRecords();
        if (records.size() != 0) {//存储不为空的module值
            records.forEach(article -> {
                VONationArticle voNationArticle = new VONationArticle();
                DataChanges.fromArticleToVONationArticle(article, voNationArticle);
                voNationArticleList.add(voNationArticle);
            });
        }
        IPage<VONationArticle> data=new Page<>(current,size);
        data.setTotal(articleIPage.getTotal());
        data.setPages(articleIPage.getPages());
        if(voNationArticleList.size()!=0) {
            data.setRecords(voNationArticleList);
        }
        voNationPage.setData(data);
        voNationPage.setCategory(categoryName);
        voNationPage.setModule(moduleName);
        return ServerResponse.createSuccessResponse("请求成功",voNationPage);
    }


    /**
     *
     * @param categoryName 模块名
     * @return
     */
    @ApiOperation("民族模块中获取某个category所有数据的接口(所有民族的，不用划分民族，即该分类中所有的文章信息)")
    @RequestMapping("/nation/category")
    private ServerResponse<VONationCategoryPage> nationMainPageByCategory(
            @RequestParam(value = "categoryName")  String categoryName){
        VONationCategoryPage voNationPage=new VONationCategoryPage();
        //每个模块的具体的数据
        if(redisService!=null&&redisService.hasKey(CommonURL.NationPageCategory+categoryName)){
            HashMap<String,List<VONationArticle>> data=new HashMap<>();
            data=(HashMap<String,List<VONationArticle>>)redisService.get(CommonURL.NationPageCategory+categoryName);
            if (data.size() != 0) {
                voNationPage.setData(data);
            }
        }else {
            HashMap<String,List<VONationArticle>> data=new HashMap<>();
            List<String> moduleName = nationUtil.getModuleName().get(categoryName);
            moduleName.forEach(module->{
                List<VONationArticle> voNationArticleList=new ArrayList<>();
                QueryWrapper<Article> qw=new QueryWrapper<>();
                qw.eq("category_name",categoryName);
                qw.eq("Module_name",module);
                qw.orderByDesc("pageview");
                IPage<Article> iPage=new Page<>(1,10);
                IPage<Article> articleIPage = articleService.page(iPage, qw);
                List<Article> records = articleIPage.getRecords();
                if(records.size()!=0) {//存储不为空的module值
                    records.forEach(article -> {
                        VONationArticle voNationArticle = new VONationArticle();
                        DataChanges.fromArticleToVONationArticle(article, voNationArticle);
                        voNationArticleList.add(voNationArticle);
                    });
                    data.put(module, voNationArticleList);
                }
            });
            if (data.size() != 0) {
                voNationPage.setData(data);
                redisService.put(CommonURL.NationPageCategory+categoryName,data,1);//设置一小时有效，一小时会自动统计阅读量，所以会更新缓存
            }
        }
        return ServerResponse.createSuccessResponse("请求成功",voNationPage);

    }

    /**此接口用于筛选符合categoryName，以及moduleName的文章集合
     *
     *
     * @param categoryName 筛选的文章种类
     * @param moduleName 筛选的模块种类
     * @return 返回符合筛选条件的文章信息
     *
     * 注意：
     *
     *  如果是从民族模块的主界面进入，那么应该传入categoryName，或者其的moduleName
     */
    @ApiOperation("民族模块中获取某个category的moduleName的所有数据的接口(所有民族的，不用划分民族，即该分类中该模块的所有的文章信息)")
    @RequestMapping("/nation/category/module")
    private ServerResponse<VONationModulePage> nationMainPageByNationNameOrCategoryOrModule(
            @RequestParam(value = "categoryName") String categoryName
            ,@RequestParam(value = "moduleName") String moduleName
            ,@RequestParam(value = "current") int current
            ,@RequestParam(value = "size") int size){
        VONationModulePage voNationPage=new VONationModulePage();
        //某个类别的某个模块的所包含的文章信息
        List<VONationArticle> voNationArticleList = new ArrayList<>();
        QueryWrapper<Article> qw = new QueryWrapper<>();
        qw.eq("category_name", categoryName);
        qw.eq("Module_name", moduleName);
        qw.orderByDesc("pageview");
        IPage<Article> iPage = new Page<>(current, size);
        IPage<Article> articleIPage = articleService.page(iPage, qw);
        List<Article> records = articleIPage.getRecords();
        if (records.size() != 0) {//存储不为空的module值
            records.forEach(article -> {
                VONationArticle voNationArticle = new VONationArticle();
                DataChanges.fromArticleToVONationArticle(article, voNationArticle);
                voNationArticleList.add(voNationArticle);
            });
        }
        IPage<VONationArticle> data=new Page<>(current,size);
        data.setTotal(articleIPage.getTotal());
        data.setPages(articleIPage.getPages());
        if(voNationArticleList.size()!=0) {
            data.setRecords(voNationArticleList);
        }
        voNationPage.setData(data);
        voNationPage.setCategory(categoryName);
        voNationPage.setModule(moduleName);
        return ServerResponse.createSuccessResponse("请求成功",voNationPage);
    }

    /**
     *
     * @param token 用户token
     * @return 返回该uid的用户的推荐内容（民族信息）
     */
    @ApiOperation("获取目标用户推荐内容的接口，再次访问表示刷新推荐内容")
    @RequestMapping("/recommendedarticle")//推荐的内容
    private ServerResponse<List<VOArticleList>> recommendedArticle(@RequestHeader(value = "token") String token){

        List<VOArticleList> reArticle =new ArrayList<>();

        if(token!=null&&!token.equals("")) {
            String uid=JwtTokenUtil.getUserId(token,audience);
            //推荐功能暂定

            reArticle=recommendedTools.recommendedArticle(uid);
            return ServerResponse.createSuccessResponse("请求成功",reArticle);

        }else{//未登录无法获得推荐
            return ServerResponse.createErrorsResponse(ResultType.TOKENNULL);
        }
    }

    /**
     *
     * @param token 用户token
     * @param module category中的某个模块名
     * @param category 大的分类名
     * @param nation 用户想要关注的民族名
     * @return
     */
    @ApiOperation("判断是否关注")
    @RequestMapping("/isattention")//判断是否关注该模块
    private ServerResponse<String> isAttention(@RequestHeader(value = "token") String token,
                                               @RequestParam("module")String module,
                                               @RequestParam("category")String category,
                                               @RequestParam("nation")String nation){
        if(token!=null&&!token.equals("")){
            String uid=JwtTokenUtil.getUserId(token,audience);
            QueryWrapper<Attention> qw=new QueryWrapper<>();
            qw.eq("module",module);
            qw.eq("category",category);
            qw.eq("uid",uid);
            qw.eq("nation",nation);
            Attention one = attentionService.getOne(qw);
            if(one!=null) return ServerResponse.createSuccessResponse("true");
            else return ServerResponse.createSuccessResponse("false");
        }else{
            return ServerResponse.createErrorsResponse(ResultType.TOKENNULL);
        }
    }

    /**
     *
     * @param token
     * @param module
     * @param category
     * @param nation
     * @return 返回关注是否成功
     */
    @ApiOperation("关注")
    @RequestMapping("/attention")//关注该模块
    private ServerResponse<String> Attention(@RequestHeader(value = "token") String token,
                                               @RequestParam("module")String module,
                                               @RequestParam("category")String category,
                                               @RequestParam("nation")String nation){
        if(token!=null&&!token.equals("")){
            String uid=JwtTokenUtil.getUserId(token,audience);
            Attention attention=new Attention();
            attention.setCategory(category);
            attention.setModule(module);
            attention.setNation(nation);
            attention.setUid(uid);
            boolean one = attentionService.save(attention);
            if(one) return ServerResponse.createSuccessResponse("true");
            else return ServerResponse.createSuccessResponse("false");
        }else{
            return ServerResponse.createErrorsResponse(ResultType.TOKENNULL);
        }
    }

    /**
     *
     * @param token
     * @param module
     * @param category
     * @param nation
     * @return 返回取消关注的状态
     */
    @ApiOperation("取消关注")
    @RequestMapping("/dropattention")//关注该模块
    private ServerResponse<String> dropAttention(@RequestHeader(value = "token") String token,
                                             @RequestParam("module")String module,
                                             @RequestParam("category")String category,
                                             @RequestParam("nation")String nation){
        if(token!=null&&!token.equals("")){
            String uid=JwtTokenUtil.getUserId(token,audience);
            QueryWrapper<Attention> qw=new QueryWrapper<>();
            qw.eq("module",module);
            qw.eq("category",category);
            qw.eq("uid",uid);
            qw.eq("nation",nation);
            boolean one = attentionService.remove(qw);
            if(one) return ServerResponse.createSuccessResponse("true");
            else return ServerResponse.createSuccessResponse("false");
        }else{
            return ServerResponse.createErrorsResponse(ResultType.TOKENNULL);
        }
    }
    @ApiOperation("不感兴趣，更新用户兴趣矩阵")
    @PostMapping("/dislikearticle")//推荐的内容
    private ServerResponse<String> dislikeArticle(@RequestHeader(value = "token") String token,
                                                 @RequestParam(value = "id")String id){

        return ServerResponse.createSuccessResponse("true");
    }

}

